package org.example.demo.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.example.demo.service.DatasourceService;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class DatasourceServiceImpl implements DatasourceService {

    @Override
    public List getTables(Connection connection) {
        List<Object> list = new ArrayList<>();
        try {
            String catalog = connection.getCatalog(); //catalog 其实也就是数据库名
            log.debug("数据库名 ======>> {}", catalog);
            DatabaseMetaData metaData = connection.getMetaData();

            List<String> types = new ArrayList<>();
            ResultSet tableTypeResultSet = metaData.getTableTypes();
            while (tableTypeResultSet.next()) {
                types.add(tableTypeResultSet.getString("TABLE_TYPE"));
            }
            log.debug("数据表类型 ======>> {}", types);
            tableTypeResultSet.close();

            ResultSet tableResultSet = metaData.getTables(catalog, null, null, new String[]{"TABLE", "VIEW"});
            while (tableResultSet.next()) {
                Map<String, Object> map = new HashMap<>();
                map.put("TABLE_CAT", tableResultSet.getString("TABLE_CAT"));
                map.put("TABLE_SCHEM", tableResultSet.getString("TABLE_SCHEM"));
                map.put("TABLE_NAME", tableResultSet.getString("TABLE_NAME"));
                map.put("TABLE_TYPE", tableResultSet.getString("TABLE_TYPE"));
                map.put("REMARKS", tableResultSet.getString("REMARKS"));
                map.put("TYPE_CAT", tableResultSet.getString("TYPE_CAT"));
                map.put("TYPE_SCHEM", tableResultSet.getString("TYPE_SCHEM"));
                map.put("TYPE_NAME", tableResultSet.getString("TYPE_NAME"));
                map.put("SELF_REFERENCING_COL_NAME", tableResultSet.getString("SELF_REFERENCING_COL_NAME"));
                map.put("REF_GENERATION", tableResultSet.getString("REF_GENERATION"));
                log.debug("数据表 ======>> {}", map);
                list.add(map);
            }
            tableResultSet.close();
        } catch (Exception e) {
            log.error("ERROR", e);
        }
        return list;
    }

    @Override
    public List getColumns(Connection connection, String tableName) {
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            String catalog = connection.getCatalog(); //catalog 其实也就是数据库名
            log.debug("数据库名 ======>> {}", catalog);
            DatabaseMetaData metaData = connection.getMetaData();

            List<String> primaryKeys = new ArrayList<>();
            ResultSet primaryKeyResultSet = metaData.getPrimaryKeys(catalog, null, tableName);
            while (primaryKeyResultSet.next()) {
                primaryKeys.add(primaryKeyResultSet.getString("COLUMN_NAME"));
            }
            log.debug("主键列 ======>> {}", primaryKeys);
            primaryKeyResultSet.close();

            ResultSet columnResultSet = metaData.getColumns(catalog, null, tableName, null);
            while (columnResultSet.next()) {
                Map<String, Object> map = new HashMap<>();
                map.put("TABLE_CAT", columnResultSet.getString("TABLE_CAT"));
                map.put("TABLE_SCHEM", columnResultSet.getString("TABLE_SCHEM"));
                map.put("TABLE_NAME", columnResultSet.getString("TABLE_NAME"));
                map.put("COLUMN_NAME", columnResultSet.getString("COLUMN_NAME"));
                map.put("DATA_TYPE", columnResultSet.getInt("DATA_TYPE"));
                map.put("TYPE_NAME", columnResultSet.getString("TYPE_NAME"));
                map.put("COLUMN_SIZE", columnResultSet.getInt("COLUMN_SIZE"));
                map.put("BUFFER_LENGTH", columnResultSet.getObject("BUFFER_LENGTH"));
                map.put("DECIMAL_DIGITS", columnResultSet.getInt("DECIMAL_DIGITS"));
                map.put("NUM_PREC_RADIX", columnResultSet.getInt("NUM_PREC_RADIX"));
                map.put("NULLABLE", columnResultSet.getInt("NULLABLE"));
                map.put("REMARKS", columnResultSet.getString("REMARKS"));
                map.put("COLUMN_DEF", columnResultSet.getString("COLUMN_DEF"));
                map.put("SQL_DATA_TYPE", columnResultSet.getInt("SQL_DATA_TYPE"));
                map.put("SQL_DATETIME_SUB", columnResultSet.getInt("SQL_DATETIME_SUB"));
                map.put("CHAR_OCTET_LENGTH", columnResultSet.getInt("CHAR_OCTET_LENGTH"));
                map.put("ORDINAL_POSITION", columnResultSet.getInt("ORDINAL_POSITION"));
                map.put("IS_NULLABLE", columnResultSet.getString("IS_NULLABLE"));
                map.put("SCOPE_CATALOG", columnResultSet.getString("SCOPE_CATALOG"));
                map.put("SCOPE_SCHEMA", columnResultSet.getString("SCOPE_SCHEMA"));
                map.put("SCOPE_TABLE", columnResultSet.getString("SCOPE_TABLE"));
                map.put("SOURCE_DATA_TYPE", columnResultSet.getShort("SOURCE_DATA_TYPE"));
                map.put("IS_AUTOINCREMENT", columnResultSet.getString("IS_AUTOINCREMENT"));
                map.put("IS_GENERATEDCOLUMN", columnResultSet.getString("IS_GENERATEDCOLUMN"));
                map.put("IS_PRIMARYKEY", primaryKeys.contains(columnResultSet.getString("COLUMN_NAME")) ? "YES" : "NO");
                log.debug("数据列 ======>> {}", map);
                list.add(map);
            }
            columnResultSet.close();
        } catch (Exception e) {
            log.error("ERROR", e);
        } finally {

        }
        return list;
    }
}
